package com.jay.io.clazz;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamException;
import java.io.Serializable;

public class ObjectStreamCls {
	public static void main(String[] args) throws ClassNotFoundException,
			IOException {
		System.out.println("-------------------");
		Message msg = (Message) serialize();
		System.out.println(msg.getHead());
		System.out.println(msg.getTag());
		System.out.println(msg.getText());
		System.out.println(msg.getB());
		System.out.println("-------------------");
		msg = (Message) serializeToFile();
		System.out.println(msg.getHead());
		System.out.println(msg.getTag());
		System.out.println(msg.getText());
		System.out.println(msg.getB());
		System.out.println("-------serializeTwice------------");
		msg = (Message) serializeTwice();
		System.out.println(msg.getHead());
		System.out.println(msg.getTag());
		System.out.println(msg.getText());
		System.out.println(msg.getB());
		System.out.println("-------serializeUnsharedTwice-----------");
		msg = (Message) serializeUnsharedTwice();
		System.out.println(msg.getHead());
		System.out.println(msg.getTag());
		System.out.println(msg.getText());
		System.out.println(msg.getB());

	}

	public static Object serialize() throws IOException, ClassNotFoundException {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		ObjectOutputStream oos = new ObjectOutputStream(baos);
		Message msg = new Message("H", 1, null, 'f');
		oos.writeObject(msg);
		ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
		ObjectInputStream ois = new ObjectInputStream(bais);
		return ois.readObject();
	}

	public static Object serializeTwice() throws IOException,
			ClassNotFoundException {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		ObjectOutputStream oos = new ObjectOutputStream(baos);
		Message msg = new Message("H", 1, null, 'f');
		oos.writeObject(msg);
		// reset 可以将第一次的放弃
		// oos.reset();
		msg.setText("Woca");
		// 只认第一次的,若没有reset
		oos.writeObject(msg);
		ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
		ObjectInputStream ois = new ObjectInputStream(bais);
		ois.readObject();
		return ois.readObject();
	}

	public static Object serializeUnsharedTwice() throws IOException,
			ClassNotFoundException {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		ObjectOutputStream oos = new ObjectOutputStream(baos);
		Message msg = new Message("H", 1, null, 'f');
		oos.writeObject(msg);
		msg.setText("Woca");
		// 只认第一次的
		oos.writeUnshared(msg);
		ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
		ObjectInputStream ois = new ObjectInputStream(bais);
		ois.readObject();
		return ois.readObject();
	}

	public static Object serializeToFile() throws IOException,
			ClassNotFoundException {
		File f = new File("object.txt");
		FileOutputStream fos = new FileOutputStream(f);
		ObjectOutputStream oos = new ObjectOutputStream(fos);
		Message msg = new Message("H", 1, null, 'f');
		oos.writeObject(msg);
		FileInputStream fis = new FileInputStream(f);
		ObjectInputStream ois = new ObjectInputStream(fis);
		return ois.readObject();
	}

}

class Message implements Serializable {
	private String head = "";
	private int tag = 0;
	private String text;
	private transient char b;

	public Message(String head, int tag, String text, char b) {
		this.head = head;
		this.tag = tag;
		this.text = text;
		this.b = b;
	}

	public char getB() {
		return b;
	}

	public void setB(char b) {
		this.b = b;
	}

	public String getHead() {
		return head;
	}

	public void setHead(String head) {
		this.head = head;
	}

	public int getTag() {
		return tag;
	}

	public void setTag(int tag) {
		this.tag = tag;
	}

	public String getText() {
		return text;
	}

	public void setText(String text) {
		this.text = text;
	}

	private void writeObject(ObjectOutputStream out) throws IOException {
		System.out.println("writeObject invoked");

		// 可以直接用default写，不用一个一个
		out.defaultWriteObject();
		// transient的default不写，需要的话要手动来
		out.writeChar(this.b);
		// out.writeObject(this.head);
		// out.writeInt(this.tag);
		// out.writeObject(this.text == null ? "hohohahaha" : this.text);
	}

	private void readObject(ObjectInputStream in) throws IOException,
			ClassNotFoundException {
		System.out.println("readObject invoked");
		// this.head = (String) in.readObject();
		// this.tag = in.readInt();
		// this.text = (String) in.readObject();
		in.defaultReadObject();
		this.b = in.readChar();
		System.out.println("got message:" + text);
	}

	private Object writeReplace() throws ObjectStreamException {
		System.out.println("writeReplace invoked");
		return this;
	}

	private Object readResolve() throws ObjectStreamException {
		System.out.println("readResolve invoked");
		return this;
	}

}